/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2002 Copyright (C)
 *
 *  File: UpgradeInterface.cpp
 *
 *  Description: implement functions interface about upgrade module
 *		         
 *  History:
 *      Date		Author      Version		Comment
 *      ====        ======      =======		=======
 *  1   2007.5.23	Tony Wang	1.0			Create
 ****************************************************************************/

#include <types.h>
#include <sys_config.h>

#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <api/libc/fastCRC.h>
#include <api/libchunk/chunk.h>
#include <bus/sci/sci.h>
#include <bus/flash/flash.h>
#include <hld/hld_dev.h>

#include "ErrorCode.h"
#include "Packet.h"

#include "UpgradeCommand.h"
#include "UpgradeCommand_old.h"
#include "UpgradeInterface.h"


#define COMTEST_DATA "@ALI PROTOCOL 3.0+"


extern UINT g_protocol_version;
/****************************************************************************
 *
 *  Name:		SetProtocolVersion()
 *	Function:	Set Client tools(Boot Loader) protocol version
 *	variable:	nProtocolVersion
 *				
 *				
 *  
 ****************************************************************************/
void SetProtocolVersion(UINT nVersion)
{
	g_protocol_version = nVersion;

}


int StrRevertCmp(char *szBuffer, char *szData)
{
	int nResult = 0;
	UINT32 i = 0;
	for(i = 0; i < STRLEN(szData); i++)
	{
		if((unsigned char)szBuffer[i] != (unsigned char)(0xFF - szData[i]))
		{
			nResult = 1;
			break;
		}

	}
	return nResult;
}

/****************************************************************************
 *
 *  Name:		cmd_comtest
 *	Function:	test serial port communication
 *	variable:	pfProgress 		-- callback function about progress
 *				pfUserAbort 	-- callback function about if user abort thread
 *				
 *  
 ****************************************************************************/

UINT32 cmd_comtest(UINT32 *pVersion, CALLBACK_PROGRESS pfProgress,  CALLBACK_USERABORT pfUserAbort)
{

	char szCommand[256]= "";
	char szData[256] = COMTEST_DATA;
	char szBuffer[128];

	sprintf(szCommand, "comtest %d\r", STRLEN(szData));

	com_clear_buffer();
	int nReturn = ERROR_NOTCONNECT;
	int i = 0;
	for(; i < COMTESTTIMES; i++) 
	{
		/* send test info*/
		if(pfUserAbort != NULL && (*pfUserAbort)() == TRUE)
		{
			nReturn = ERROR_USERABORT;
			break;
		}

		if(pfProgress != NULL && ( i % 5 == 0))
			(*pfProgress)(i);
		
		Sleep(50);
		com_clear_buffer();
		
		
		UINT32 nLen = STRLEN(szCommand);
/*		if(nLen != com_send((unsigned char *)szCommand, nLen))
		{
			com_send_char('\r');
			continue;
		}
		MEMSET(szBuffer, 0, 128);
		if(SUCCESS != com_read_tm((unsigned char *)szBuffer, nLen, 500))
		{
			com_send_char('\r');
			continue;		
		}

		if(STRCMP(szCommand, szBuffer) != 0)
		{
//			com_send_char('\r');
			continue;
		}
*/
		if(com_send2back_tm((unsigned char *)szCommand, nLen, 50) != SUCCESS)
		{
			com_send_char('\r');
			continue;
		}
				
		nLen = STRLEN(szData);
		if(nLen != com_send((unsigned char *)szData, nLen) )
			continue;

		MEMSET(szBuffer, 0, 128);
		if(SUCCESS == com_read_tm((unsigned char *)szBuffer, nLen, 100))
		{
			szBuffer[nLen] = 0;
			if(STRCMP(szBuffer, szData) == 0)
				*pVersion = 0x20;
			else if(StrRevertCmp(szBuffer, szData) == 0)
				*pVersion = 0x30;
			else
				continue;
			
			nReturn = SUCCESS;
			break;
		}
	}
	SetProtocolVersion(*pVersion);
	return nReturn;
}

/****************************************************************************
 *
 *  Name:		cmd_version
 *	Function:	command version return chunk info
 *	variable:	pVersion		-- protocol version (return value)
 *				
 *				
 *				
 *  
 ****************************************************************************/
UINT32 cmd_version(UINT32 *pVersion)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
	{
		nResult = cmd_version_new(pVersion);
		
#ifdef _S3281_	
		;
#else
		if(SUCCESS == nResult)
			nResult = cmd_chunk_new();
#endif

	}
	else
	{
		nResult = cmd_version_old(pVersion);
	}

	return nResult;
}

	
/****************************************************************************
 *
 *  Name:		cmd_address
 *	Function:	set start address
 *	variable:	addr -- start address
 *				
 *				
 *  
 ****************************************************************************/
UINT32 cmd_address(UINT32 addr)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_address_new(addr);
	else
		nResult = cmd_address_old(addr);

	return nResult; 
}
/****************************************************************************
 *
 *  Name:		cmd_move
 *	Function:	move chunk
 *	variable:	index -- chunk index
 *				offset - chunk offset
 *				
 *  
 ****************************************************************************/
UINT32 cmd_move(UINT32 index,UINT32 offset)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_move_new(index, offset);
	else
		nResult = cmd_move_old(index, offset);

	return nResult; 
}

/****************************************************************************
 *
 *  Name:		cmd_transfer
 *	Function:	move chunk
 *	variable:	buffer - data buffer for transfer
 *				nBufLen	-- buffer len
 *				pfProgress 		-- callback function about progress
 *				pfUserAbort 	-- callback function about if user abort thread
 *  
 ****************************************************************************/
UINT32 cmd_transfer(unsigned char *buffer, int nBufLen, 
		CALLBACK_PROGRESS pfProgress,  CALLBACK_USERABORT pfUserAbort)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_transfer_new(buffer, nBufLen, pfProgress, pfUserAbort);
	else
		nResult = cmd_transferraw_old(buffer, nBufLen, pfProgress, pfUserAbort);

	return nResult; 
}


/****************************************************************************
 *
 *  Name:		cmd_burn
 *	Function:	burn flash
 *	variable:	pfProgress 		-- callback function about progress
 *				
 *								
 *  
 ****************************************************************************/
UINT32 cmd_burn(int nBurnSize, CALLBACK_PROGRESS pfProgress, BOOL bCareReturn)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_burn_new(nBurnSize, pfProgress, bCareReturn);
	else
		nResult = cmd_burn_old(nBurnSize, pfProgress, bCareReturn);
	return nResult;
}

/****************************************************************************
 *
 *  Name:		cmd_burn_ext
 *	Function:	burn flash, with user abort
 *	variable:	pfProgress 		-- callback function about progress
 *				
 *								
 *  
 ****************************************************************************/
UINT32 cmd_burn_ext(int nBurnSize, CALLBACK_PROGRESS pfProgress, BOOL bCareReturn,  CALLBACK_USERABORT pfUserAbort)
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_burn_new_ext(nBurnSize, pfProgress, bCareReturn, pfUserAbort);
	else
		nResult = cmd_burn_old(nBurnSize, pfProgress, bCareReturn);
	return nResult;
}

/****************************************************************************
 *
 *  Name:		cmd_reboot
 *	Function:	reboot target
 *	variable:	
 *				
 *				
 *  
 ****************************************************************************/
UINT32 cmd_reboot()
{
	UINT32 nResult = SUCCESS;
	if(g_protocol_version >= NEW_PROTOCOL_VERSION)
		nResult = cmd_reboot_new();
	else
		nResult = cmd_reboot_old();
	return nResult;
}


